import {nextTick} from 'vue';
import * as svg from '@element-plus/icons-vue';
import router from '/@/router/index';
import pinia from '/@/stores/index';
import {storeToRefs} from 'pinia';
import {useThemeConfig} from '/@/stores/themeConfig';

// 引入组件
import {Pane, Splitpanes} from "splitpanes";
import ZTable from "/@/components/Z-Table/index.vue"
import ZStepController from "/@/components/Z-StepController/index.vue"
import ZApiReport from "/@/components/Z-Report/ApiReport/index.vue"
import MonacoEditor from "/@/components/monaco/index.vue"
import ZDetailPageHeader from "/@/components/Z-DetailPageHeader/index.vue"
import SvgIcon from "/@/components/svgIcon/index.vue"
import {verifyUrl} from "/@/utils/toolsValidate";
import {Local} from "/@/utils/storage";


/**
 * 导出全局注册 zero table
 * @param app vue 实例
 */
export function ZeroTable(app) {
	app.component('z-table', ZTable);
}

/**
 * 导出全局注册 Step Controller
 * @param app vue 实例
 */

export function ZeroStepController(app) {
	app.component('z-step-controller', ZStepController);

}

/**
 * 导出全局注册 Step Controller
 * @param app vue 实例
 */

export function ZeroApiReport(app) {
	app.component('z-api-report', ZApiReport);
}

/**
 * 导出全局注册 ZeroApiDetail
 * @param app vue 实例
 */

/**
 * 导出全局注册 splitpanes.scss
 * @param app vue 实例
 */
export function splitpanes(app) {
	app.component('z-splitpanes', Splitpanes);
	app.component('z-pane', Pane);
}

/**
 * 导出全局注册 monacoEditor
 * @param app vue 实例
 */

export function monaco(app) {
	app.component('z-monaco-editor', MonacoEditor);
}

/**
 * 导出全局注册 Z-DetailPageHeader
 * @param app vue 实例
 */

export function ZeroDetailPageHeader(app) {
	app.component('z-detail-page-header', ZDetailPageHeader);
}


/**
 * 导出全局注册 element plus svg 图标
 * @param app vue 实例
 * @description 使用：https://element-plus.gitee.io/zh-CN/component/icon.html
 */
export function elSvg(app) {
	const icons = svg;
	for (const i in icons) {
		app.component(`ele-${icons[i].name}`, icons[i]);
	}
	app.component('SvgIcon', SvgIcon);
}

/**
 * 设置浏览器标题国际化
 * @method const title = useTitle(); ==> title()
 */
export function useTitle() {
	const stores = useThemeConfig(pinia);
	const {themeConfig} = storeToRefs(stores);
	nextTick(() => {
		let webTitle = '';
		let globalTitle = themeConfig.value.globalTitle;
		const {path, meta} = router.currentRoute.value;
		if (path === '/login') {
			webTitle = meta.title;
		} else {
			webTitle = setTagsViewNameI18n(router.currentRoute.value);
		}
		document.title = `${webTitle} - ${globalTitle}` || globalTitle;
	});
}

/**
 * 设置 自定义 tagsView 名称
 * @param params 路由 query、params 中的 tagsViewName
 * @returns 返回当前 tagsViewName 名称
 */
export function setTagsViewNameI18n(item) {
	let tagsViewName = '';
	const {query, params, meta} = item;
	if (query?.tagsViewName || params?.tagsViewName) {
		// 非国际化
		tagsViewName = query?.tagsViewName || params?.tagsViewName;
	} else {
		// 非自定义 tagsView 名称
		tagsViewName = meta.title;
	}
	return tagsViewName;
}

/**
 * 图片懒加载
 * @param el dom 目标元素
 * @param arr 列表数据
 * @description data-xxx 属性用于存储页面或应用程序的私有自定义数据
 */
export const lazyImg = (el, arr) => {
	const io = new IntersectionObserver((res) => {
		res.forEach((v) => {
			if (v.isIntersecting) {
				const {img, key} = v.target.dataset;
				v.target.src = img;
				v.target.onload = () => {
					io.unobserve(v.target);
					arr[key]['loading'] = false;
				};
			}
		});
	});
	nextTick(() => {
		document.querySelectorAll(el).forEach((img) => io.observe(img));
	});
};

/**
 * 全局组件大小
 * @returns 返回 `window.localStorage` 中读取的缓存值 `globalComponentSize`
 */
export const globalComponentSize = () => {
	const stores = useThemeConfig(pinia);
	const {themeConfig} = storeToRefs(stores);
	return Local.get('themeConfig')?.globalComponentSize || themeConfig.value?.globalComponentSize;
};

/**
 * 对象深克隆
 * @param obj 源对象
 * @returns 克隆后的对象
 */
export function deepClone(obj) {
	let newObj;
	try {
		newObj = obj.push ? [] : {};
	} catch (error) {
		newObj = {};
	}
	for (let attr in obj) {
		if (obj[attr] && typeof obj[attr] === 'object') {
			newObj[attr] = deepClone(obj[attr]);
		} else {
			newObj[attr] = obj[attr];
		}
	}
	return newObj;
}

/**
 * 判断是否是移动端
 */
export function isMobile() {
	if (
		navigator.userAgent.match(
			/('phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone')/i
		)
	) {
		return true;
	} else {
		return false;
	}
}

/**
 * 判断数组对象中所有属性是否为空，为空则删除当前行对象
 * @description @感谢大黄
 * @param list 数组对象
 * @returns 删除空值后的数组对象
 */
export function handleEmpty(list) {
	const arr = [];
	for (const i in list) {
		const d = [];
		for (const j in list[i]) {
			// @ts-ignore
			d.push(list[i][j]);
		}
		const leng = d.filter((item) => item === '').length;
		if (leng !== d.length) {
			// @ts-ignore
			arr.push(list[i]);
		}
	}
	return arr;
}

/**
 * 打开外部链接
 * @param val 当前点击项菜单
 */
export function handleOpenLink(val) {
	const {origin, pathname} = window.location;
	router.push(val.path);
	if (verifyUrl(val.meta?.isLink)) window.open(val.meta?.isLink);
	else window.open(`${origin}${pathname}#${val.meta?.isLink}`);
}

/**
 * 统一批量导出
 * @method elSvg 导出全局注册 element plus svg 图标
 * @method useTitle 设置浏览器标题国际化
 * @method setTagsViewNameI18n 设置 自定义 tagsView 名称、 自定义 tagsView 名称国际化
 * @method lazyImg 图片懒加载
 * @method globalComponentSize() element plus 全局组件大小
 * @method deepClone 对象深克隆
 * @method isMobile 判断是否是移动端
 * @method handleEmpty 判断数组对象中所有属性是否为空，为空则删除当前行对象
 */
const other = {
	apiPublicAssembly: (app) => {
		ZeroTable(app);
		// ZeroApiDetail(app);
		ZeroStepController(app);
		ZeroApiReport(app);
		ZeroDetailPageHeader(app);
		splitpanes(app);
		monaco(app);
		elSvg(app);
	},
	useTitle: () => {
		useTitle();
	},
	setTagsViewNameI18n(route) {
		return setTagsViewNameI18n(route);
	},
	lazyImg: (el, arr) => {
		lazyImg(el, arr);
	},
	globalComponentSize: () => {
		return globalComponentSize();
	},
	deepClone: (obj) => {
		return deepClone(obj);
	},
	isMobile: () => {
		return isMobile();
	},
	handleEmpty: (list) => {
		return handleEmpty(list);
	},
	handleOpenLink: (val) => {
		handleOpenLink(val);
	},
};

// 统一批量导出
export default other;
